package main

import (
	"errors"
	"fmt"
	"grpc-server/pb"
	"io"
	"log"
	"net"
	"time"

	"golang.org/x/net/context"
	"google.golang.org/grpc"
	"google.golang.org/grpc/credentials"
	"google.golang.org/grpc/metadata"
)

const port = ":5001"

func main() {

	listen, err := net.Listen("tcp", port)
	if err != nil {
		log.Fatalln(err.Error())
	}
	creds, err := credentials.NewServerTLSFromFile("cert.pem", "key.pem")
	if err != nil {
		log.Fatalln(err.Error())
	}

	options := []grpc.ServerOption{grpc.Creds(creds)}

	server := grpc.NewServer(options...)

	pb.RegisterEmployeeServiceServer(server, new(employeeService))

	log.Println("grpc server started..." + port)
	server.Serve(listen)

}

type employeeService struct{}

func (s *employeeService) GetByNo(ctx context.Context, req *pb.GetByNoRequest) (*pb.EmployeeResponse, error) {

	for _, e := range employees {
		if req.No == e.No {
			return &pb.EmployeeResponse{
				Employee: &e,
			}, nil
		}
	}
	return nil, errors.New("Employee not found")
}

func (s *employeeService) GetAll(req *pb.GetAllRequest, stream pb.EmployeeService_GetAllServer) error {

	for _, e := range employees {
		stream.Send(&pb.EmployeeResponse{
			Employee: &e,
		})
		time.Sleep(2 * time.Second)
	}
	return nil
}

func (s *employeeService) AddPhoto(stream pb.EmployeeService_AddPhotoServer) error {

	md, ok := metadata.FromIncomingContext(stream.Context())

	if ok {
		fmt.Printf("Employee: %s\n", md["no"][0])
	}

	img := []byte{}

	for {
		data, err := stream.Recv()

		if err == io.EOF {
			fmt.Printf("File Size:%d\n", len(img))
			return stream.SendAndClose(&pb.AddPhotoResponse{IsOk: true})
		}

		if err != nil {
			return err
		}

		fmt.Printf("File received: %d\n", len(data.Data))
		img = append(img, data.Data...)

	}
	return nil
}

func (s *employeeService) Save(context.Context, *pb.EmployeeRequest) (*pb.EmployeeResponse, error) {
	return nil, nil
}

func (s *employeeService) SaveAll(stream pb.EmployeeService_SaveAllServer) error {

	for {
		empReq, err := stream.Recv()

		if err == io.EOF {
			break
		}

		if err != nil {
			return err
		}

		employees = append(employees, *empReq.Employee)

		stream.Send(&pb.EmployeeResponse{Employee: empReq.Employee})
	}

	for _, emp := range employees {
		fmt.Println(emp)
	}

	return nil

}
